using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AdminApiTemplate.Common.Helpers
{
    public class LogHelper
    {
        private static readonly string _baseDirectory = AppDomain.CurrentDomain.BaseDirectory;

        private static readonly object _lock = new object();

        public static void Write(string message)
        {
            Write(message, null);
        }

        public static void Write(string message, string directoryName)
        {
            Write(message, directoryName, null);
        }

        public static void Write(string message, string directoryName, string fileName)
        {
            lock (_lock)
            {
                if (string.IsNullOrEmpty(message))
                {
                    return;
                }

                string logDirectory;
                if (string.IsNullOrEmpty(directoryName))
                {
                    logDirectory = Path.Combine(new string[] { _baseDirectory ?? "", "Log" });
                }
                else
                {
                    logDirectory = Path.Combine(new string[] { _baseDirectory ?? "", "Log", directoryName });
                }

                if (!Directory.Exists(logDirectory))
                {
                    Directory.CreateDirectory(logDirectory);
                }

                var dt = DateTime.Now;
                if (string.IsNullOrEmpty(fileName))
                {
                    fileName = dt.ToString("yyyy-MM-dd") + ".txt";
                }

                var filepath = Path.Combine(new string[] { logDirectory, fileName });
                using (var sw = new StreamWriter(filepath, true, Encoding.UTF8))
                {
                    sw.WriteLine(dt.ToString("yyyy-MM-dd HH:mm:ss"));
                    sw.WriteLine(message);
                    sw.WriteLine();
                }
            }
        }

        public static void WriteAsync(string message)
        {
            WriteAsync(message, null);
        }

        public static void WriteAsync(string message, string directoryName)
        {
            WriteAsync(message, directoryName, null);
        }

        public static void WriteAsync(string message, string directoryName, string fileName)
        {
            Task.Run(() =>
            {
                try
                {
                    WriteAsync(new WriteLogSettings
                    {
                        Content = message,
                        DirectoryName = directoryName,
                        FileName = fileName
                    });
                }
                catch
                { }
            });
        }

        private static void WriteAsync(WriteLogSettings settings)
        {
            Write(settings.Content, settings.DirectoryName, settings.FileName);
        }

        public static void WriteDebug(string message)
        {
            Write(message, "Debug");
        }

        public static void WriteDebug(string message, string fileName)
        {
            Write(message, "Debug", fileName);
        }

        public static void WriteDebugAsync(string message)
        {
            WriteAsync(message, "Debug");
        }

        public static void WriteDebugAsync(string message, string fileName)
        {
            WriteAsync(message, "Debug", fileName);
        }

        public static void WriteError(string message)
        {
            Write(message, "Error");
        }

        public static void WriteError(string message, string fileName)
        {
            Write(message, "Error", fileName);
        }

        public static void WriteErrorAsync(string message)
        {
            WriteAsync(message, "Error");
        }

        public static void WriteErrorAsync(string message, string fileName)
        {
            WriteAsync(message, "Error", fileName);
        }
    }

    public class WriteLogSettings
    {
        public string Content { get; set; }

        public string DirectoryName { get; set; }

        public string FileName { get; set; }
    }
}
